package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.BFeeModelEnum;
import cn.huiyunche.base.service.enums.BFeeTypeEnum;
import cn.huiyunche.base.service.interfaces.BFeeModelService;
import cn.huiyunche.base.service.interfaces.BFeeTypeService;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

@Service
public class BFeeTypeServiceImpl implements BFeeTypeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BFeeTypeServiceImpl.class);

    @Autowired
    private BFeeModelService bFeeModelService;

    @Autowired
    private BFeeTypeMapper bFeeTypeMapper;

    @Autowired
    private SInsuranceFeeMapper sInsuranceFeeMapper;

    @Autowired
    private SExtractFeeMapper sExtractFeeMapper;

    @Autowired
    private SDeliveryFeeMapper deliveryFeeMapper;

    @Autowired
    private SShippingFeeMapper shippingFeeMapper;

    @Autowired
    private SInvoiceRateMapper sInvoiceRateMapper;

    @Override
    public SInsuranceFee getSInsuranceFeesByFeeCode(BFeeType feeType, BigDecimal valuation) {
        LOGGER.info("getSInsuranceFeesByFeeCode params : {}, {}", feeType.getId(), valuation);
        if (null == valuation) {
            LOGGER.error("valuation must not be null");
            throw new BusinessException("估值不能为空！");
        }

        SInsuranceFeeExample example = new SInsuranceFeeExample();
        example.createCriteria().andFeeTypeIdEqualTo(feeType.getId()).andBeginRangeLessThanOrEqualTo(valuation.multiply(BigDecimal.valueOf(10000))).andEndRangeGreaterThanOrEqualTo(valuation.multiply(BigDecimal.valueOf(10000)));
        List<SInsuranceFee> list = sInsuranceFeeMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("getSInsuranceFeesByFeeCode list is empty");
            throw new BusinessException("获取保险费信息失败！");
        }
        //计算折扣
        SInsuranceFee insuranceFee = list.get(0);
        insuranceFee.setPrice(insuranceFee.getPrice().multiply(feeType.getDiscount()));
        return insuranceFee;
    }

    @Override
    public List<BFeeType> getByCode(Long feeModelId, List<Integer> feeCodes) {
        LOGGER.info("getByCode params : {}, {}", feeModelId, feeCodes);
        BFeeTypeExample example = new BFeeTypeExample();
        BFeeTypeExample.Criteria criteria = example.createCriteria().andFeeModelIdEqualTo(feeModelId);
        if (CollectionUtils.isNotEmpty(feeCodes)) {
            criteria.andFeeCodeIn(feeCodes);
        }
        List<BFeeType> list = bFeeTypeMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("getByCode list is empty");
            throw new BusinessException("获取费用类型信息失败！");
        }
        return list;
    }

    @Override
    public SExtractFee getExtractFeeByFeeCode(BFeeTypeEnum extract) {
        LOGGER.info("getExtractFeeByFeeCode param : {}", extract.getValue());

        //查询费用类型信息
        BFeeType feeType = this.getByCode(bFeeModelService.getByCode(BFeeModelEnum.INTERCITY_ORDER).getId(), Arrays.asList(extract.getValue())).get(0);

        SExtractFeeExample example = new SExtractFeeExample();
        example.createCriteria().andFeeTypeIdEqualTo(feeType.getId());
        List<SExtractFee> list = sExtractFeeMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("getExtractFeeByFeeCode list is empty");
            throw new BusinessException("获取提车费信息失败！");
        }

        //计算折扣
        SExtractFee extractFee = list.get(0);
        extractFee.setPrice(extractFee.getPrice().multiply(feeType.getDiscount()));

        return extractFee;
    }

    @Override
    public SDeliveryFee getDeliveryFeeByFeeCode(BFeeTypeEnum delivery) {
        LOGGER.info("getDeliveryFeeByFeeCode param : {}", delivery.getValue());

        //查询费用类型信息
        BFeeType feeType = this.getByCode(bFeeModelService.getByCode(BFeeModelEnum.INTERCITY_ORDER).getId(), Arrays.asList(delivery.getValue())).get(0);

        SDeliveryFeeExample example = new SDeliveryFeeExample();
        example.createCriteria().andFeeTypeIdEqualTo(feeType.getId());
        List<SDeliveryFee> list = deliveryFeeMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("getDeliveryFeeByFeeCode list is empty");
            throw new BusinessException("获取提车费信息失败！");
        }

        //计算折扣
        SDeliveryFee deliveryFee = list.get(0);
        deliveryFee.setPrice(deliveryFee.getPrice().multiply(feeType.getDiscount()));

        return deliveryFee;
    }

    @Override
    public SShippingFee getShippingFeeByFeeCode(BFeeTypeEnum shipping, BigDecimal distance) {
        LOGGER.info("getShippingFeeByFeeCode params : {}, {}", shipping.getValue(), distance);

        //查询费用类型信息
        BFeeType feeType = this.getByCode(bFeeModelService.getByCode(BFeeModelEnum.INTERCITY_ORDER).getId(), Arrays.asList(shipping.getValue())).get(0);

        SShippingFeeExample example = new SShippingFeeExample();
        example.createCriteria().andFeeTypeIdEqualTo(feeType.getId()).andBeginRangeLessThanOrEqualTo(distance).andEndRangeGreaterThanOrEqualTo(distance);
        List<SShippingFee> list = shippingFeeMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("getShippingFeeByFeeCode list is empty");
            throw new BusinessException("获取提车费信息失败！");
        }

        //计算折扣
        SShippingFee shippingFee = list.get(0);
        shippingFee.setRate(shippingFee.getRate().multiply(feeType.getDiscount()));
        shippingFee.setSubsidy(shippingFee.getSubsidy().multiply(feeType.getDiscount()));

        return shippingFee;
    }

    @Override
    public List<BFeeType> getListByFeeModelId(long feeModelId) {
        LOGGER.info("getListByFeeModelId param : {}", feeModelId);
        if (0 == feeModelId) {
            LOGGER.error("getListByFeeModelId feeModelId must not be 0");
            throw new IllegalArgumentException("费用模型id不能是0！");
        }

        BFeeTypeExample example = new BFeeTypeExample();
        example.createCriteria().andFeeModelIdEqualTo(feeModelId);
        List<BFeeType> list = bFeeTypeMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("getListByFeeModelId list is empty");
            throw new BusinessException("获取费用类型信息失败！");
        }

        return list;
    }

    /**
     * 查询费用类型
     *
     * @param example
     * @return
     */
    @Override
    public BFeeType selectByExample(BFeeTypeExample example) {
        LOGGER.info("selectByExample param : {}", example);
        try {
            LOGGER.info("selectByExample select feetype by example params : {}.", example);
            return bFeeTypeMapper.selectByExample(example).get(0);
        } catch (Exception e) {
            LOGGER.error("selectByExample select feetype by example error : {}.", e);
            throw new BusinessException("查询费用类型异常");
        }
    }

    @Override
    public SInvoiceRate getSIvoiceRateByFeeCode(Long feeTypeId) {
        LOGGER.info("getSIvoiceRateByFeeCode param : {}", feeTypeId);
        if (null == feeTypeId) {
            LOGGER.error("getSIvoiceRateByFeeCode feeTypeId must not be null");
            throw new IllegalArgumentException("费用类型id不能为空");
        }

        SInvoiceRateExample example = new SInvoiceRateExample();
        example.createCriteria().andFeeTypeIdEqualTo(feeTypeId);
        List<SInvoiceRate> list = sInvoiceRateMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("getSIvoiceRateByFeeCode list must not be empty");
            throw new BusinessException("获取发票费费率失败！");
        }
        return list.get(0);
    }

}